﻿/**
   * jQuery ligerUI 1.1.9
   * 
   * http://ligerui.com
   * 
   * Author daomi 2012 [ gd_star@163.com ]
   * 
   */
(function($){
  $.fn.ligerForm=function(){
    return $.ligerui.run.call(this,"ligerForm",arguments);
  };
  
  $.ligerDefaults=$.ligerDefaults||{};
  $.ligerDefaults.Form={
    // 控件宽度
    inputWidth:180,
    // 标签宽度
    labelWidth:90,
    // 间隔宽度
    space:40,
    rightToken:'：',
    // 标签对齐方式
    labelAlign:'left',
    // 控件对齐方式
    align:'left',
    // 字段
    fields:[],
    // 创建的表单元素是否附加ID
    appendID:true,
    // 生成表单元素ID的前缀
    prefixID:"",
    // json解析函数
    toJSON:$.ligerui.toJSON
  };
  
  // @description 默认表单编辑器构造器扩展(如果创建的表单效果不满意 建议重载)
  // @param {jinput} 表单元素jQuery对象 比如input、select、textarea
  $.ligerDefaults.Form.editorBulider=function(jinput,fieldOptions){
    // 这里this就是form的ligerui对象
    var g=this,p=this.options;
    var inputOptions=fieldOptions||{};
    var ltype=jinput.attr("ltype");
    if(!g.fields) //add by franky
      g.fields=[];
    var field;
    if(p.inputWidth)
      inputOptions.width=p.inputWidth;
    if(jinput.is("select")){
      field=jinput.ligerComboBox(inputOptions);
    }else if(jinput.is(":text")||jinput.is(":password")){
      switch(ltype){
        case "select":
        case "combobox":
          field=jinput.ligerComboBox(inputOptions);
          break;
        case "spinner":
          field=jinput.ligerSpinner(inputOptions);
          break;
        case "date":
          field=jinput.ligerDateEditor(inputOptions);
          break;
        case "float":
        case "number":
          inputOptions.number=true;
          field=jinput.ligerTextBox(inputOptions);
          break;
        case "int":
        case "digits":
          inputOptions.digits=true;
        default:
          field=jinput.ligerTextBox(inputOptions);
          break;
      }
    }else if(jinput.is(":hidden")){
      field={type:'Hidden',options:inputOptions,destroy:$.noop};
    }else if(jinput.is(":radio")){
      field=jinput.ligerRadio(inputOptions);
    }else if(jinput.is(":checkbox")){
      field=jinput.ligerCheckBox(inputOptions);
    }else if(ltype=="textarea"){
      field=jinput.ligerTextAreaBox(inputOptions);
      /*jinput.addClass("l-textarea");
      if(jinput.attr('required'))
        jinput.addClass("l-text-required");
      if(jinput.attr('readOnly'))
        jinput.addClass("l-text-readonly");*/
    }else if(ltype=="kindeditor"){
      field=jinput.ligerKindEditor(inputOptions);
    }
    if(field)
      g.fields.push(field);// add by franky
  }
  
  // 表单组件
  $.ligerui.controls.Form=function(element,options){
    $.ligerui.controls.Form.base.constructor.call(this,element,options);
  };
  
  $.ligerui.controls.Form.ligerExtend($.ligerui.core.UIComponent,{
    __getType:function(){
      return 'Form'
    },
    __idPrev:function(){
      return 'Form';
    },
    _init:function(){
      $.ligerui.controls.Form.base._init.call(this);
    },
    _render:function(){
      var g=this,p=this.options;
      var jform=$(this.element);
      var fieldOptionsMap={};
      // 自动创建表单
      if(p.fields&&p.fields.length){
        if(!jform.hasClass("l-form"))
          jform.addClass("l-form");
        var out=[];
        var appendULStartTag=false;
        $(p.fields).each(function(index,field){
          var name=field.name||field.id;
          var id=field.id||field.name;
          if(!name)
            return;
          if(field.type=="hidden"){
            out.push('<input type="hidden" id="'+id+'" name="'+name+'" value="'+(field.value||'')+'" />');
          }
          else{
            var newLine=field.renderToNewLine||field.newline;
            if(newLine==null)
              newLine=true;
            if(field.merge)
              newLine=false;
            if(field.group)
              newLine=true;
            if(newLine){
              if(appendULStartTag){
                out.push('</ul>');
                appendULStartTag=false;
              }
              if(field.group){
                out.push('<div class="l-group');
                if(field.groupicon)
                  out.push(' l-group-hasicon');
                out.push('">');
                if(field.groupicon)
                  out.push('<img src="'+field.groupicon+'" />');
                out.push('<span>'+field.group+'</span></div>');
              }
              out.push('<ul');
              if(field.hidden){ //addy by franky, implement hide field function.
                out.push(' class="l-hidden"')
              }
              out.push(">")
              appendULStartTag=true;
            }
            // append label
            out.push(g._buliderLabelContainer(field));
            // append input
            out.push(g._buliderControlContainer(field));
            // append space
            out.push(g._buliderSpaceContainer(field));
          }
          fieldOptionsMap[id]=field;
        });
        if(appendULStartTag){
          out.push('</ul>');
          appendULStartTag=false;
        }
        jform.append(out.join(''));
      }
      // 生成ligerui表单样式
      $("input,select,textarea",jform).each(function(){
        var $field=$(this);
        p.editorBulider.call(g,$field,fieldOptionsMap[$field[0].id]); //modify by franky, add paramter:fieldoptions, for fix the issue of disabled:true not effectived
      });
    },
    // 标签部分
    _buliderLabelContainer:function(field){
      var g=this,p=this.options;
      var label=field.label||field.display;
      var labelWidth=field.labelWidth||field.labelwidth||p.labelWidth;
      var labelAlign=field.labelAlign||p.labelAlign;
      if(label)
        label+=p.rightToken;
      var out=[];
      out.push('<li style="');
      if(labelWidth){
        out.push('width:'+labelWidth+'px;');
      }
      if(labelAlign){
        out.push('text-align:'+labelAlign+';');
      }
      out.push('">');
      if(label){
        out.push(label);
      }
      out.push('</li>');
      return out.join('');
    },
    // 控件部分
    _buliderControlContainer:function(field){
      var g=this,p=this.options;
      var width=field.width||p.inputWidth;
      var align=field.align||field.textAlign||field.textalign||p.align;
      var out=[];
      out.push('<li style="');
      if(width&&field.type!='textarea'&&field.type!='kindeditor'){ //modify by franky
        out.push('width:'+width+'px;');
      }
      if(align){
        out.push('text-align:'+align+';');
      }
      out.push('">');
      out.push(g._buliderControl(field));
      out.push('</li>');
      return out.join('');
    },
    // 间隔部分
    _buliderSpaceContainer:function(field){
      var g=this,p=this.options;
      var spaceWidth=field.space||field.spaceWidth||p.space;
      var out=[];
      out.push('<li style="');
      if(spaceWidth){
        out.push('width:'+spaceWidth+'px;');
      }
      out.push('">');
      out.push('</li>');
      return out.join('');
    },
    _buliderControl:function(field){
      var g=this,p=this.options;
      var width=field.width||p.inputWidth;
      var id=field.id||field.name;
      var name=field.name||'';
      var out=[];
      if(field.comboboxName&&field.type=="select"){
        out.push('<input type="hidden" id="'+p.prefixID+name+'" name="'+name+'" value="'+field.value+'" />');
      }
      else if(field.type=="textarea"){ //modify by franky
        out.push('<textarea ');
        if(typeof(width)=='number')
          out.push('style="width:'+width+'px;"');
        else if(typeof(width)=='string')
          out.push('style="width:'+width);
      }else if(field.type=="kindeditor"){//modify by franky
        out.push('<textarea ');
        out.push('style="width:auto;"');
      }else if(field.type=="checkbox"){
        out.push('<input type="checkbox" ');
      }else if(field.type=="radio"){
        out.push('<input type="radio" ');
      }else if(field.type=="password"){
        out.push('<input type="password" ');
      }else{
        out.push('<input type="text" ');
      }
      if(field.cssClass){
        out.push('class="'+field.cssClass+'" ');
      }
      if(field.type){
        out.push('ltype="'+field.type+'" ');
      }
      if(field.attr){
        for(var attrp in field.attr){
          out.push(attrp+'="'+field.attr[attrp]+'" ');
        }
      }
      if(field.comboboxName&&field.type=="select"){
        out.push('name="'+field.comboboxName+'"');
        if(p.appendID){
          out.push(' id="'+p.prefixID+field.comboboxName+'" ');
        }
      }else{
        out.push('name="'+name+'"');
        if(p.appendID){
          out.push(' id="'+id+'" ');
        }
      }
      if(field.value){
          out.push(' value="'+field.value+'" ');
      }
      if((p.disabled!=undefined||p.disabled!=null)&&(field.disabled==null||field.disabled==undefined)){  //add by franky
        field.disabled=p.disabled;
      }
      if((p.readOnly!=undefined||p.readOnly!=null)&&(field.readOnly==null||field.readOnly==undefined)){  //add by franky
        field.readOnly=p.readOnly; 
      }
      if(p.disabled)          //必填属性  //add by franky
      out.push(' disabled');
      if(field.required||p.required)          //必填属性  //add by franky
      out.push(' required');
      if(field.readOnly||p.readOnly)          //只读属性  //add by franky
      out.push(' readonly');
      // 参数
      field.options=$.extend(field.options,field.validate);
      var fieldOptions=$.extend({
        width:width-2
      },field.options||{});
      out.push(" ligerui='"+p.toJSON(fieldOptions)+"' ");
      // 验证参数
      if(field.validate){
        field.validate.required=field.options.required;
        out.push(" validate='"+p.toJSON(field.validate)+"' ");
      }
      out.push(' />');
      return out.join('');
    },
    /**
     * load form data if data is a URL string type load from remote site, otherwise load from local
     * data object.
     */
    load:function(data){ //add by franky
      if(typeof data=='string'){
        var frm=this;
        $.ajax({
          url:data,
          dataType:'json',
          //type:'get',
          success:function(res){
            frm.setValues(res);
          },
          complete:function(xhr,textStatus){
            xhr=null;
          },
          error:function(xmlHttpRequest,textStatus,errorThrown){
            xmlHttpRequest=null;
            alert("数据返回错误:"+errorThrown.message);
          }
        });
      }else{
        this.setValues(res);
      }
    },
    setValues:function(data){ //add by franky
      for(var i=0;i<this.fields.length;i++){
        var field=this.fields[i];
        if(field.type=='Hidden'){
           var name=field.options.name||field.options.id;
           if(name in data){
           var value=data[name];
              $("#"+name).val(value);
           }
        }
        else if(field.type!='ComboBox'){
           var name=field.options.name||field.options.id;
           var value=data[name];
           if(value){
              field._setValue(value);
           }
        }
        else{
          var hiddenFieldName=field.options.hiddenFieldName;
          var value=data[hiddenFieldName];
          if(value){
            var displayFieldName=field.options.name;
            if(!displayFieldName){
	            var pattern=/^.*id$/i;
	            var displayFieldName=pattern.test(name)?name.substring(0,name.length-2).concat("Name"):name.concat("Name");
            }
            var displayText=data[displayFieldName];
            field._setValue(value,displayText);
          }
        }
      }
    },    
    getValues:function(){
      function arrayToJson(o){
        var v={};
        for(var i=0;i<o.length;i++){
          if(typeof(v[o[i].name])=="undefined")
            v[o[i].name]=o[i].value;
          else
            v[o[i].name]+=","+o[i].value;
        }
        return v;
      }
      return arrayToJson($(this.element).serializeArray());
    },
    reset:function(){ //add by franky
      var form=this.element;
      form.reset();
      $('select',form).each(function(index,element){
        var select=$(this);
         select.ligerComboBox().selectValue(select.val());
      });
    },
    cleanInvalid:function(){//add by franky
      var form=this.element;
      $('.l-textarea-invalid,.l-text-invalid',form).each(function(index,element){
        var element=$(element);
        element.removeClass("l-textarea-invalid");
        element.removeClass("l-text-invalid");
        element.find("input.error").removeClass("error");
        var nextCell=element.parents("td:first").next("td");
        nextCell.find("div.l-exclamation").remove();
      });
    },    
    validate:function(){ //add by franky
      $.metadata.setType("attr","validate");
      var v=$(this.element).validate({
        // 调试状态，不会提交数据的
        debug:false,
        errorPlacement:function(lable,element){
          if(element.hasClass("l-textarea")){
            element.addClass("l-textarea-invalid");
          }else if(element.hasClass("l-text-field")){
            element.parent().addClass("l-text-invalid");
          }
          var nextCell=element.parents("td:first").next("td");
          nextCell.find("div.l-exclamation").remove();
          $('<div class="l-exclamation" title="'+lable.html()+'"></div>').appendTo(nextCell).ligerTip();
        },
        success:function(lable){
          var element=$("#"+lable.attr("for"));
          var nextCell=element.parents("td:first").next("td");
          if(element.hasClass("l-textarea")){
            element.removeClass("l-textarea-invalid");
          }else if(element.hasClass("l-text-field")){
            element.parent().removeClass("l-text-invalid");
          }
          nextCell.find("div.l-exclamation").remove();
        },
        submitHandler:function(){
          alert("Submitted!");
        }
      });
      return v.form();
    },
    destroy:function(){ //add by franky, auto destroy fields, but has a bug for textarea because of no ligerTextArea UI component, anyway, this method is worked.
      for(var i=0;i<this.fields.length;i++){
        this.fields[i].destroy();
      }
      this.constructor.base.destroy.call(this);
    }
  });
})(jQuery);